#include <thread>
#include "erpc/erpc.h"
#include "spd_logger.hpp"
#include "simpost_component.hpp"
#include "module/module_name.hpp"
#include "module/module_identity.pb.h"
#include "google/protobuf/wrappers.pb.h"

class subscribAPP: public simpost::Component
{
public:
    explicit subscribAPP() : Component("subscriber", "V0.1.0") {}
    virtual ~subscribAPP() = default;
    bool init(void) override final;
    void exit(void) override final;
private:
    void subscriberAPP(void);
    void topicDataHandler(const google::protobuf::Any &args);
};

bool subscribAPP::init(void)
{
    LOG_INFO("subscribAPP init");
    std::thread app([this]{ subscriberAPP(); });
    app.detach();
    return true;
}

void subscribAPP::exit(void)
{
    LOG_INFO("subscribAPP exit");
}

void subscribAPP::subscriberAPP(void)
{
    google::protobuf::Any args;
    google::protobuf::Int32Value value;
    std::this_thread::sleep_for(std::chrono::milliseconds(20));
    erpc::erpc_topic_subscribe("publisher", MODULE_ID_ACCESS, MODULE_ID_ACCESS, 15, std::bind(&subscribAPP::topicDataHandler, this, std::placeholders::_1));
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(3));
        if(false == erpc::erpc_topic_fetch("publisher", MODULE_ID_ACCESS, 15, args, 100))
        {
            LOG_ERROR("fetch 'publishAPP/15' data failed!");
            continue;
        }
        args.UnpackTo(&value);
        LOG_INFO("fetch topic 'publishAPP/15' data: {}", value.value());
    }
}

void subscribAPP::topicDataHandler(const google::protobuf::Any &args)
{
    google::protobuf::Int32Value value;
    if(!args.UnpackTo(&value))
    {
        LOG_ERROR("unpack 'publishAPP/15' data failed!");
        return;
    }
    LOG_INFO("recv topic 'publishAPP/15' data: {}", value.value());
}

COMPONENT_REGISTER(subscribAPP);